package com.chenjt.jvm.second.four_classLife;

import java.util.Random;

/**
 * 注释：
 *
 * 4.当使用java.lang.reflect包中的方法反射类的方法时。比如:Class.forName("com.chenjt.java.Test”)
 * 5.当初始化子类时，如果发现其父类还没有进行过初始化，则需要先触发其父类的初始化。
 *    如果针对代码，设置参数-XX:+TraceClassLoading，可以追踪类的加载信息并打印出来
 * 6.如果一个接口定义了default方法，那么直接实现或者间接实现该接口的类的初始化，该接口要在其之前被初始化。
 * 7.当虚拟机启动时，用户需要指定一个要执行的主类(包含main()方法的那个类)，虚拟机会先初始化这个主类。
 * 8.当初次调用 MethodHand1e 实例时，初始化该 MethodHandle 指向的方法所在的类。
 *  (涉及解析REF_getStatic、REF_putStatic、REF_invokeStatic方法句柄对应的类)
 *
 *
 * 针对5，补充说明:
 * 当Java虚拟机初始化一个类时，要求它的所有父类都已经被初始化了，但是这条规则并不适用接口
 * > 在初始化一个类时，并不会先初始化它所实现的接口
 * > 在初始化一个接口时，并不会先初始化它的父接口
 * 因此，一个父接口并不会因为它的子接口或者实现类的初始化而初始化。只有当程序首次使用特定
 * 接口的静态字段时，才会导致该接口的初始化。
 *
 * @author chenjt
 * @date 2025/7/2 8:59
 */
public class ActiveUse3 {

    static{
        System.out.println("ActiveUse3的初始化过程");
    }

    public static void main(String[] args) {
        /**
         * 会先初始化当前类（ActiveUse3）
         * 输出：
         *  ActiveUse3的初始化过程
         *  hello
         * 7.当虚拟机启动时，用户需要指定一个要执行的主类(包含main()方法的那个类)，虚拟机会先初始化这个主类。
         */
        System.out.println("hello");
    }

    public static void test1() {
        try {
            // 4.当使用java.lang.reflect包中的方法反射类的方法时。比如:Class.forName("com.chenjt.java.Test”)
            // 会执行类的<clinit>方法
            Class.forName("com.chenjt.jvm.second.four_classLife.Order");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }


    public static void test2(){
        /**
         * CompareB接口没有default方法
         * 5.当初始化子类时，如果发现其父类还没有进行过初始化，则需要先触发其父类的初始化。
         *  如果针对代码，设置参数-XX:+TraceClassLoading，可以追踪类的加载信息并打印出来
         */
        System.out.println(Son.num);
    }


    public static void test3(){
        /**
         * 当接口中有对象的引用时会执行类的<clinit>方法
         * new Random().nextInt();
         */
        System.out.println(CompareC.NUM1);
    }


    public static void test4(){
        /**
         * 接口增加了default方法
         * 6.如果一个接口定义了default方法，那么直接实现或者间接实现该接口的类的初始化，该接口要在其之前被初始化。
         */
        System.out.println(Son.num);
    }


}

class Father{
    static{
        System.out.println("Father类的初始化过程");
    }
}

class Son extends Father implements CompareB{
    static{
        System.out.println("Son类的初始化过程");
    }

    public static int num = 1;

}


interface CompareB{

    public static final Thread t = new Thread(){
        {
            System.out.println("CompareB的初始化");
        }
    };

    // 6.如果一个接口定义了default方法，那么直接实现或者间接实现该接口的类的初始化，该接口要在其之前被初始化。
    public default void method1(){
        System.out.println("hello");
    }


}


interface CompareC extends CompareB{

    public static final Thread t = new Thread(){
        {
            System.out.println("CompareC的初始化");
        }
    };

    public static final int NUM1 = new Random().nextInt();

}



